package com.aryankh.aspect;

import com.aryankh.annotation.Log;
import com.aryankh.core.RedisTemplate;
import com.aryankh.entity.KhOperLog;
import com.aryankh.service.KhOperLogService;
import com.aryankh.utils.AuthUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Objects;

/**
 * @version 1.0
 * @Author AryanKH
 * @Date 2022/6/3 16:40
 * @Default
 */
@Component
@Aspect
@Slf4j
public class LogAspect{
    @Resource
    private KhOperLogService khOperLogService;
    @Resource
    RedisTemplate redisTemplate;

//    @Resource
//    ExecutorService executorService;

//    private BeanFactory beanFactory;
//    @Override
//    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
//        this.beanFactory=beanFactory;
//    }
    @AfterReturning("@annotation(operLog)")
    public void afterReturning(JoinPoint joinPoint, Log operLog) {
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        System.out.println("main-------------"+Thread.currentThread().getName());
        KhOperLog khOperLog = createOperLog(request, operLog, joinPoint, null);
        //这个service是异步的
        khOperLogService.insert(khOperLog);
        log.info("{}执行了{}操作",khOperLog.getOperName(),khOperLog.getOperName());

//        LogAspect logAspect = beanFactory.getBean(this.getClass());
//        logAspect.logHandler(khOperLog);
    }

    @AfterThrowing(value = "@annotation(operLog)", throwing = "exception")
    public void afterThrowing(JoinPoint joinPoint, Log operLog, Exception exception) {
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        KhOperLog khOperLog = createOperLog(request, operLog, joinPoint, exception);
//        LogAspect logAspect = beanFactory.getBean(this.getClass());
//        logAspect.logHandler(khOperLog);
        khOperLogService.insert(khOperLog);
        log.error("{}执行了 {}操作 发生了{}",khOperLog.getOperName(),khOperLog.getOperName(),exception.getMessage());
    }


//    private void logHandler(HttpServletRequest request, Log operLog, JoinPoint joinPoint, Exception exception) {
//        //当大量的请求,会导致线程数突增
//        /*new Thread(() -> {
//
//        }).start();*/
//        //这样也不行 每次请求都会创建一个线程池,所以建议线程池是单例的
//        /*ExecutorService executorService = Executors.newFixedThreadPool(10);
//        executorService.execute(() -> {
//
//        });*/
//        //提交任务.
//        //1.根据现场信息封装日志实例
//        KhOperLog khOperLog = new KhOperLog();
//        khOperLog.setTitle(operLog.title());
//        khOperLog.setBusinessType(operLog.bussinessType());
//        if (exception != null) {
//            khOperLog.setErrormsg(exception.getMessage().length() > 1000 ?
//                    exception.getMessage().substring(0, 1000):exception.getMessage());
//            khOperLog.setStatus(500);
//        } else {
//            khOperLog.setStatus(200);
//        }
//        //request 当中获取的信息
//        khOperLog.setOperIp(request.getRemoteAddr());
//        khOperLog.setRequestMethod(request.getMethod());
//        // 注意空指针的问题
//        if (((AuthUtil.getLoginUser(redisTemplate) != null) && (AuthUtil.getLoginUser(redisTemplate).getKhUser().getUserName() != null))) {
//            khOperLog.setOperName(AuthUtil.getLoginUser(redisTemplate).getKhUser().getUserName());
//        }
//
//        khOperLog.setOperUrl(request.getRequestURI());
//        String methodName = joinPoint.getSignature().getName();
//        khOperLog.setMethod(methodName);
//        khOperLog.setOpertime(new Date());
//        executorService.execute(() -> {
//            khOperLogService.insert(khOperLog);
//        });
//    }

//    @Async("kh_logger")
//    public void logHandler(KhOperLog khOperLog) {
//        khOperLogService.insert(khOperLog);
//    }

    private KhOperLog createOperLog(HttpServletRequest request, Log log, JoinPoint joinPoint, Exception exception) {
        System.out.println("operLog-------------"+Thread.currentThread().getName());
        //提交任务.
        //1.根据现场信息封装日志实例
        KhOperLog khOperLog = new KhOperLog();
        khOperLog.setTitle(log.title());
        khOperLog.setBusinessType(log.bussinessType());
        if (exception != null) {
            khOperLog.setErrormsg(exception.getMessage().length() > 1000 ?
                    exception.getMessage().substring(0, 1000): exception.getMessage());
            khOperLog.setStatus(500);
        } else {
            khOperLog.setStatus(200);
        }
        //request 当中获取的信息
        khOperLog.setOperIp(request.getRemoteAddr());
        khOperLog.setRequestMethod(request.getMethod());
        // 注意空指针的问题
        if (((AuthUtil.getLoginUser(redisTemplate) != null) && (AuthUtil.getLoginUser(redisTemplate).getKhUser().getUserName() != null))) {
            khOperLog.setOperName(AuthUtil.getLoginUser(redisTemplate).getKhUser().getUserName());
        }

        khOperLog.setOperUrl(request.getRequestURI());
        String methodName = joinPoint.getSignature().getName();
        khOperLog.setMethod(methodName);
        khOperLog.setOpertime(new Date());
        return khOperLog;
    }

}
